#ifndef RCOCORE_H
#define RCOCORE_H

#include "rcocore_global.h"
#include "rcoimp/cmdparser.h"
#include "rcoimp/workthread.h"
#include <QPair>
#include <QTcpServer>
#include <QVector>
#include <QString>
#include <QMap>

namespace rco {

namespace inner{
struct _RcoThreadAutoPtrFree
{
	void operator()(RcoWorkThread* p)
	{
		if (p)
			p->exit();
	}
};
}

class RCOCORE_EXPORT RcoCore
	: public QTcpServer
{
	Q_OBJECT
protected:
	typedef kbase::AutoFreePtr<RcoWorkThread, inner::_RcoThreadAutoPtrFree> AutoFreeWorkThread;
	typedef QPair<RcoWorkThread*, CmdHandlerResult> RcoTaskItem;
	typedef QMap<int, RcoTaskItem>		RcoTasks;
	typedef QVector<AutoFreeWorkThread> RcoWorkThreads;

public:
	RcoCore(QObject* parent);
	~RcoCore();

	bool Init();
	bool IsAcceptConnection() const;
	void SetAcceptConnection(bool bAccept);
	bool IsAutoCreateThread() const;
	void SetAutoCreateThread(bool bCreate);
	RcoWorkThread* GetThread(int iTaskId);
	CmdHandlerResult GetTaskStatus(int iTaskId);

	CmdParserResult OnCommandParsing(const QString& strCmd, RcoCommand* pRcoCmd, int* pPosParsed);
	CmdParserResult OnCommandParsing(const wchar_t* str, RcoCommand* pRcoCmd, int* pPosParsed);
	CmdParserResult OnCommandParsing(const char* str, RcoCommand* pRcoCmd, int* pPosParsed);

signals:
	void TaskReport(int iTaskId, const RcoBuffer& content);

protected:
	void incomingConnection(int socektId);

public slots:
	bool PickOneThreadToPursuit(const RcoCommandHead& rcoCmdHead, RcoBuffer& bytes, RcoIODevice* who);
	void TaskDone(RcoWorkThread* thread, RcoCommandHead* rcoCmdHead, RcoBuffer* bytes);

protected:
	RcoTaskItem FindItem(int iTaskId);

	int				m_iTaskIdSeq;
	bool			m_bAutoCreateThread;
	bool			m_bAcceptConn;
	QByteArray		m_dataBlock;
	RcoCmdParser	m_cmdParser;
	QString			m_strCurPath;
	RcoTasks		m_TasksStatus;
	RcoWorkThreads	m_wkThreads;
	RcoWorkThread	m_queryThread;
};

}

#endif // RCOCORE_H
